#include <windows.h>
#include <iostream>
#include <C:\AMD\Support\LDPC\Headers\ldpcg2.h>
#include <C:\AMD\Support\LDPC\Headers\ldpc3.h>
#include <C:\AMD\Support\LDPC\Headers\ldpcent.h>

#define DEG 4											//maximum degree vector size
#define THREAD_MAX 8									//maximum threads vector size

double steps[DEG + 1] = {1, 0.5, 0.25, 0.1, 0.05};			//steps vector
int degrees[DEG] = {100000, 300000, 500000, 1000000};			//degree vector
int runs[THREAD_MAX] = {1, 4, 5};				//threads to run

DWORD WINAPI ThreadFunc(void* numb)
{
	// Parameter of ldpcent(mi, pi1, Kappa, errorcount1, rounds, EbNo, EbNoend, stepsize, itmax, n, k, timeT, degrees, threadNumb)

	cout << "Thread " << ((int)numb + 1) << " is running!" << endl;

    if ((int)numb == 0)		ldpcent(0.99, 0.1, 10, 0, 0, 6, 9, steps, 100, 1000, 500, 0, degrees, (int)numb);
    if ((int)numb == 1)		ldpc3(0.99, 0.1, 10, 0, 0, 1, 9, 1, 100, 1000, 500, 0, (int)numb);
    if ((int)numb == 2)		ldpcg2(0.1, 0.1, 10, 0, 0, 1, 9, 1, 100, 1000, 500, 0, (int)numb);
    if ((int)numb == 3)		ldpcent(0.95, 0.1, 10, 0, 0, 1, 5, steps, 100, 1000, 500, 0, degrees, (int)numb);
	if ((int)numb == 4)		ldpcent(0.90, 0.1, 10, 0, 0, 1, 5, steps, 100, 1000, 500, 0, degrees, (int)numb);
    if ((int)numb == 5)		ldpcent(0.99, 0.1, 10, 0, 0, 1, 5, steps, 100, 1000, 500, 0, degrees, (int)numb);
    if ((int)numb == 6)		ldpcent(0.99, 0.1, 10, 0, 0, 1, 5, steps, 100, 1000, 500, 0, degrees, (int)numb);
    if ((int)numb == 7)		ldpcent(0.99, 0.1, 10, 0, 0, 1, 5, steps, 100, 1000, 500, 0, degrees, (int)numb);

    return 0;
}

DWORD WINAPI Run(void* numb)
{
	for(int i = 0; i < THREAD_MAX; i++)											//for size of 'runs'
	{
		if(runs[i] != 0)														//if position of runs vector isn't zero
			if(runs[i] == ((int)numb + 1))	ThreadFunc(numb);					//if the number of thread is marked to run, run
	}

	return 0;
}

int main()
{
  HANDLE threads[THREAD_MAX];							//Threads vector - size: THREAD_MAX

  for (int i = 0; i < THREAD_MAX; i++)					//Create THREAD_MAX threads
  {
      threads[i] = CreateThread(NULL, 0, Run, (void*)i, 0, NULL);			//'Run' is the main function of the thread - 'i' is the number of thread
  }
  WaitForMultipleObjects(THREAD_MAX, threads, TRUE, INFINITE);			//Wait the end of threads (number of threads, threads vector, wait all?, time to wait)

  for (int i = 0; i < THREAD_MAX ; i++)					//Close the threads
  {
      CloseHandle(threads[i]);
	  cout << "Thread " << (i+1) << " closed!" << endl;
  }
  return 0;
}
